{
 "cells": [
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "%env LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1\n",
    "%env LLM_API_KEY=sk-替换为自己的Key"
   ],
   "id": "3ebb9dc12396a96c"
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4e8b146c-8aa6-4932-a0d1-9d1eb10fa284",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:35.401750Z",
     "iopub.status.busy": "2025-01-16T14:09:35.401555Z",
     "iopub.status.idle": "2025-01-16T14:09:35.404346Z",
     "shell.execute_reply": "2025-01-16T14:09:35.403881Z",
     "shell.execute_reply.started": "2025-01-16T14:09:35.401736Z"
    }
   },
   "outputs": [],
   "source": "!pip install lightrag-hku aioboto3 ollama nano_vectordb langchain langchain-community langchain-openai langchain_chroma pypdf sentence_transformers shutil openpyxl FlagEmbedding"
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "923402dd-c259-4665-9a29-cb1ef09aaf81",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:35.588319Z",
     "iopub.status.busy": "2025-01-16T14:09:35.588151Z",
     "iopub.status.idle": "2025-01-16T14:09:37.335694Z",
     "shell.execute_reply": "2025-01-16T14:09:37.335209Z",
     "shell.execute_reply.started": "2025-01-16T14:09:35.588305Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lightrag  \t1.1.2\n",
      "aioboto3  \t13.3.0\n",
      "nano_vectordb\t0.0.4.1\n"
     ]
    }
   ],
   "source": [
    "import os, lightrag, aioboto3, nano_vectordb\n",
    "\n",
    "for module in (lightrag, aioboto3, nano_vectordb):\n",
    "    print(f\"{module.__name__:<10}\\t{module.__version__}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0a993b3-2810-44e7-9abf-edeec9d79dba",
   "metadata": {},
   "source": [
    "在Notebook中需要这个，否则会报错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e2c2db11-74b1-489d-a2de-e87bc54fb472",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:37.336678Z",
     "iopub.status.busy": "2025-01-16T14:09:37.336432Z",
     "iopub.status.idle": "2025-01-16T14:09:37.339409Z",
     "shell.execute_reply": "2025-01-16T14:09:37.339019Z",
     "shell.execute_reply.started": "2025-01-16T14:09:37.336663Z"
    }
   },
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "nest_asyncio.apply()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b6bdc42e-ca70-4897-84f1-48882bbc7c91",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:37.339931Z",
     "iopub.status.busy": "2025-01-16T14:09:37.339806Z",
     "iopub.status.idle": "2025-01-16T14:09:37.353567Z",
     "shell.execute_reply": "2025-01-16T14:09:37.353039Z",
     "shell.execute_reply.started": "2025-01-16T14:09:37.339918Z"
    }
   },
   "outputs": [],
   "source": [
    "expr_version = 'kg_v01_lightrag'\n",
    "\n",
    "preprocess_output_dir = os.path.join(os.path.pardir, 'outputs', 'v1_20240713')\n",
    "expr_dir = os.path.join(os.path.pardir, 'experiments', expr_version)\n",
    "\n",
    "os.makedirs(expr_dir, exist_ok=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73ea7022-a7a6-451e-954b-0cf6427f6b85",
   "metadata": {},
   "source": [
    "# 准备文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "353d4058-7b59-47ff-b41f-39b215a11df8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:37.781839Z",
     "iopub.status.busy": "2025-01-16T14:09:37.781657Z",
     "iopub.status.idle": "2025-01-16T14:09:39.488111Z",
     "shell.execute_reply": "2025-01-16T14:09:39.487591Z",
     "shell.execute_reply.started": "2025-01-16T14:09:37.781824Z"
    }
   },
   "outputs": [],
   "source": [
    "from langchain_community.document_loaders import PyPDFLoader\n",
    "\n",
    "loader = PyPDFLoader(os.path.join(os.path.pardir, 'data', '2024全球经济金融展望报告.pdf'))\n",
    "documents = loader.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c2702155-3dea-416a-b16c-34bf23865eda",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:39.489053Z",
     "iopub.status.busy": "2025-01-16T14:09:39.488871Z",
     "iopub.status.idle": "2025-01-16T14:09:39.686254Z",
     "shell.execute_reply": "2025-01-16T14:09:39.685775Z",
     "shell.execute_reply.started": "2025-01-16T14:09:39.489039Z"
    }
   },
   "outputs": [],
   "source": [
    "import re\n",
    "\n",
    "pattern = r\"^全球经济金融展望报告\\n中国银行研究院 \\d+ 2024年\"\n",
    "processed_texts = '\\n'.join(re.sub(pattern, '', doc.page_content) for doc in documents)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e108e754-715a-4b83-9c82-ea957b719fe4",
   "metadata": {},
   "source": [
    "# 准备LightRAG"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fb794b4-a4e9-48a2-8f47-1cd01fcd2713",
   "metadata": {},
   "source": [
    "## 创建LightRAG实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4ab6297a-7092-4d34-a2e4-063fc2fea5af",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:39.686870Z",
     "iopub.status.busy": "2025-01-16T14:09:39.686737Z",
     "iopub.status.idle": "2025-01-16T14:09:39.703126Z",
     "shell.execute_reply": "2025-01-16T14:09:39.702704Z",
     "shell.execute_reply.started": "2025-01-16T14:09:39.686857Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "device: cuda\n"
     ]
    }
   ],
   "source": [
    "from langchain.embeddings import HuggingFaceBgeEmbeddings\n",
    "from langchain_community.vectorstores import Chroma\n",
    "import torch\n",
    "import numpy as np\n",
    "\n",
    "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "print(f'device: {device}')\n",
    "\n",
    "def get_embeddings(model_path):\n",
    "    embeddings = HuggingFaceBgeEmbeddings(\n",
    "        model_name=model_path,\n",
    "        model_kwargs={'device': device},\n",
    "        encode_kwargs={'normalize_embeddings': True},\n",
    "        # show_progress=True\n",
    "        query_instruction='为这个句子生成表示以用于检索相关文章：'\n",
    "    )\n",
    "    return embeddings\n",
    "\n",
    "async def hf_ollama_embedding(texts: list[str], hf_embed_model) -> np.ndarray:\n",
    "    embed_text = []\n",
    "    for text in texts:\n",
    "        data = hf_embed_model.embed_query(text)\n",
    "        embed_text.append(data)\n",
    "\n",
    "    return np.array(embed_text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "941b4025-f89d-499c-9e3c-f78763d18243",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:39.704041Z",
     "iopub.status.busy": "2025-01-16T14:09:39.703901Z",
     "iopub.status.idle": "2025-01-16T14:09:42.342751Z",
     "shell.execute_reply": "2025-01-16T14:09:42.342305Z",
     "shell.execute_reply.started": "2025-01-16T14:09:39.704027Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:numexpr.utils:NumExpr defaulting to 8 threads.\n",
      "INFO:datasets:PyTorch version 2.3.1 available.\n",
      "INFO:datasets:JAX version 0.4.26 available.\n",
      "INFO:sentence_transformers.SentenceTransformer:Load pretrained SentenceTransformer: /DataScience/HuggingFace/Models/BAAI/bge-large-zh-v1.5\n",
      "INFO:lightrag:Logger initialized for working directory: ../experiments/kg_v01_lightrag\n",
      "INFO:lightrag:Load KV json_doc_status_storage with 0 data\n",
      "INFO:lightrag:Load KV llm_response_cache with 308 data\n",
      "INFO:lightrag:Load KV full_docs with 1 data\n",
      "INFO:lightrag:Load KV text_chunks with 52 data\n",
      "INFO:lightrag:Loaded graph from ../experiments/kg_v01_lightrag/graph_chunk_entity_relation.graphml with 499 nodes, 72 edges\n",
      "INFO:nano-vectordb:Load (431, 1024) data\n",
      "INFO:nano-vectordb:Init {'embedding_dim': 1024, 'metric': 'cosine', 'storage_file': '../experiments/kg_v01_lightrag/vdb_entities.json'} 431 data\n",
      "INFO:nano-vectordb:Load (72, 1024) data\n",
      "INFO:nano-vectordb:Init {'embedding_dim': 1024, 'metric': 'cosine', 'storage_file': '../experiments/kg_v01_lightrag/vdb_relationships.json'} 72 data\n",
      "INFO:nano-vectordb:Load (52, 1024) data\n",
      "INFO:nano-vectordb:Init {'embedding_dim': 1024, 'metric': 'cosine', 'storage_file': '../experiments/kg_v01_lightrag/vdb_chunks.json'} 52 data\n",
      "INFO:lightrag:Loaded document status storage with 1 records\n"
     ]
    }
   ],
   "source": [
    "from lightrag import LightRAG\n",
    "from lightrag.llm import ollama_model_complete\n",
    "from lightrag.utils import EmbeddingFunc\n",
    "\n",
    "model_path = 'BAAI/bge-large-zh-v1.5'\n",
    "embeddings = get_embeddings(model_path)\n",
    "rag = LightRAG(\n",
    "    working_dir=expr_dir,\n",
    "    llm_model_func=ollama_model_complete,\n",
    "    llm_model_name='qwen2:7b-instruct-32k',\n",
    "    chunk_token_size=500,\n",
    "    chunk_overlap_token_size=50,\n",
    "    embedding_func=EmbeddingFunc(\n",
    "        embedding_dim=1024,\n",
    "        max_token_size=500,\n",
    "        func=lambda texts: hf_ollama_embedding(\n",
    "            texts,\n",
    "            hf_embed_model=embeddings\n",
    "        )\n",
    "        # func=lambda texts: ollama_embedding(\n",
    "        #     texts,\n",
    "        #     embed_model=\"znbang/bge:large-zh-v1.5-q8_0\"\n",
    "        # )\n",
    "        # func=lambda text: hf_embedding(\n",
    "        #     text,\n",
    "        #     tokenizer=AutoTokenizer.from_pretrained(model_path),\n",
    "        #     embed_model=AutoModel.from_pretrained(model_path, device_map=device)\n",
    "        # )\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1137089c-ce93-49af-88fa-487557afe76a",
   "metadata": {},
   "source": [
    "## 建立索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9c048fb0-68c5-4f1a-ae26-d9438a016e71",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T14:09:42.343925Z",
     "iopub.status.busy": "2025-01-16T14:09:42.343507Z",
     "iopub.status.idle": "2025-01-16T14:28:26.435467Z",
     "shell.execute_reply": "2025-01-16T14:28:26.435004Z",
     "shell.execute_reply.started": "2025-01-16T14:09:42.343908Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:Processing 1 new unique documents\n",
      "Processing batch 1:   0%|                                                                                                                              | 0/1 [00:00<?, ?it/s]INFO:lightrag:Inserting 52 vectors to chunks\n",
      "\n",
      "Generating embeddings:   0%|                                                                                                                        | 0/2 [00:00<?, ?batch/s]\u001B[A\n",
      "Generating embeddings:  50%|████████████████████████████████████████████████████████                                                        | 1/2 [00:02<00:02,  2.07s/batch]\u001B[A\n",
      "Generating embeddings: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:03<00:00,  1.64s/batch]\u001B[A\n",
      "\n",
      "Level 2 - Extracting entities and relationships:   0%|                                                                                             | 0/52 [00:00<?, ?chunk/s]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:   2%|█▌                                                                                | 1/52 [03:32<3:00:17, 212.11s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:   4%|███▏                                                                               | 2/52 [03:44<1:18:41, 94.43s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:   6%|████▉                                                                                | 3/52 [03:49<43:51, 53.70s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:   8%|██████▌                                                                              | 4/52 [03:51<26:40, 33.35s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  10%|████████▏                                                                            | 5/52 [04:12<22:32, 28.78s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  12%|█████████▊                                                                           | 6/52 [04:22<17:17, 22.55s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  13%|███████████▍                                                                         | 7/52 [04:27<12:33, 16.75s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  15%|█████████████                                                                        | 8/52 [04:30<09:08, 12.46s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  17%|██████████████▋                                                                      | 9/52 [04:34<06:54,  9.64s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  19%|████████████████▏                                                                   | 10/52 [04:37<05:22,  7.68s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  21%|█████████████████▊                                                                  | 11/52 [04:41<04:34,  6.69s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  23%|███████████████████▍                                                                | 12/52 [04:46<03:58,  5.95s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  25%|█████████████████████                                                               | 13/52 [04:49<03:18,  5.09s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  27%|██████████████████████▌                                                             | 14/52 [04:52<02:54,  4.58s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  29%|████████████████████████▏                                                           | 15/52 [05:06<04:31,  7.33s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  31%|█████████████████████████▊                                                          | 16/52 [05:08<03:32,  5.89s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  33%|███████████████████████████▍                                                        | 17/52 [09:55<52:40, 90.29s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  35%|█████████████████████████████                                                       | 18/52 [09:59<36:29, 64.41s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  37%|██████████████████████████████▋                                                     | 19/52 [10:12<26:59, 49.06s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  38%|████████████████████████████████▎                                                   | 20/52 [10:17<19:02, 35.71s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  40%|█████████████████████████████████▉                                                  | 21/52 [10:21<13:33, 26.25s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  42%|███████████████████████████████████▌                                                | 22/52 [10:25<09:48, 19.62s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  44%|█████████████████████████████████████▏                                              | 23/52 [10:34<07:57, 16.45s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  46%|██████████████████████████████████████▊                                             | 24/52 [10:39<06:02, 12.96s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  48%|████████████████████████████████████████▍                                           | 25/52 [10:43<04:36, 10.23s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  50%|██████████████████████████████████████████                                          | 26/52 [10:47<03:36,  8.32s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  52%|███████████████████████████████████████████▌                                        | 27/52 [10:51<02:58,  7.16s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  54%|█████████████████████████████████████████████▏                                      | 28/52 [10:56<02:29,  6.25s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  56%|██████████████████████████████████████████████▊                                     | 29/52 [10:59<02:04,  5.41s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  58%|████████████████████████████████████████████████▍                                   | 30/52 [11:03<01:50,  5.03s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  60%|██████████████████████████████████████████████████                                  | 31/52 [11:08<01:44,  4.98s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  62%|███████████████████████████████████████████████████▋                                | 32/52 [11:23<02:37,  7.85s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  63%|█████████████████████████████████████████████████████▎                              | 33/52 [15:14<23:40, 74.78s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  65%|██████████████████████████████████████████████████████▉                             | 34/52 [15:24<16:37, 55.43s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  67%|████████████████████████████████████████████████████████▌                           | 35/52 [15:36<12:01, 42.42s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  69%|██████████████████████████████████████████████████████████▏                         | 36/52 [15:55<09:26, 35.38s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  71%|███████████████████████████████████████████████████████████▊                        | 37/52 [16:07<07:04, 28.30s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  73%|█████████████████████████████████████████████████████████████▍                      | 38/52 [16:14<05:09, 22.10s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  75%|███████████████████████████████████████████████████████████████                     | 39/52 [16:20<03:43, 17.17s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  77%|████████████████████████████████████████████████████████████████▌                   | 40/52 [16:26<02:46, 13.89s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  79%|██████████████████████████████████████████████████████████████████▏                 | 41/52 [16:32<02:05, 11.45s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  81%|███████████████████████████████████████████████████████████████████▊                | 42/52 [16:36<01:32,  9.25s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  83%|█████████████████████████████████████████████████████████████████████▍              | 43/52 [16:40<01:08,  7.64s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  85%|███████████████████████████████████████████████████████████████████████             | 44/52 [16:44<00:51,  6.49s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  87%|████████████████████████████████████████████████████████████████████████▋           | 45/52 [16:47<00:39,  5.61s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  88%|██████████████████████████████████████████████████████████████████████████▎         | 46/52 [16:51<00:30,  5.06s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  90%|███████████████████████████████████████████████████████████████████████████▉        | 47/52 [16:55<00:24,  4.83s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  92%|█████████████████████████████████████████████████████████████████████████████▌      | 48/52 [16:59<00:18,  4.55s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  94%|███████████████████████████████████████████████████████████████████████████████▏    | 49/52 [17:46<00:51, 17.30s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  96%|████████████████████████████████████████████████████████████████████████████████▊   | 50/52 [17:53<00:28, 14.23s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships:  98%|██████████████████████████████████████████████████████████████████████████████████▍ | 51/52 [18:04<00:13, 13.11s/chunk]\u001B[A\n",
      "Level 2 - Extracting entities and relationships: 100%|████████████████████████████████████████████████████████████████████████████████████| 52/52 [18:12<00:00, 11.73s/chunk]\u001B[A\n",
      "                                                                                                                                                                             \u001B[A\n",
      "\n",
      "Level 3 - Inserting entities:   0%|                                                                                                              | 0/489 [00:00<?, ?entity/s]\u001B[A\u001B[A\n",
      "\n",
      "Level 3 - Inserting entities: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 489/489 [00:12<00:00, 37.66entity/s]\u001B[A\u001B[A\n",
      "\n",
      "                                                                                                                                                                             \u001B[A\u001B[A\n",
      "\n",
      "\n",
      "Level 3 - Inserting relationships:   0%|                                                                                                    | 0/91 [00:00<?, ?relationship/s]\u001B[A\u001B[A\u001B[A\n",
      "\n",
      "\n",
      "                                                                                                                                                                             \u001B[A\u001B[A\u001B[AINFO:lightrag:Inserting 489 vectors to entities\n",
      "\n",
      "Generating embeddings:   0%|                                                                                                                       | 0/16 [00:00<?, ?batch/s]\u001B[A\n",
      "Generating embeddings:   6%|██████▉                                                                                                        | 1/16 [00:00<00:10,  1.46batch/s]\u001B[A\n",
      "Generating embeddings:  12%|█████████████▉                                                                                                 | 2/16 [00:01<00:09,  1.42batch/s]\u001B[A\n",
      "Generating embeddings:  19%|████████████████████▊                                                                                          | 3/16 [00:02<00:09,  1.44batch/s]\u001B[A\n",
      "Generating embeddings:  25%|███████████████████████████▊                                                                                   | 4/16 [00:02<00:08,  1.43batch/s]\u001B[A\n",
      "Generating embeddings:  31%|██████████████████████████████████▋                                                                            | 5/16 [00:03<00:07,  1.44batch/s]\u001B[A\n",
      "Generating embeddings:  38%|█████████████████████████████████████████▋                                                                     | 6/16 [00:04<00:07,  1.43batch/s]\u001B[A\n",
      "Generating embeddings:  44%|████████████████████████████████████████████████▌                                                              | 7/16 [00:04<00:06,  1.46batch/s]\u001B[A\n",
      "Generating embeddings:  50%|███████████████████████████████████████████████████████▌                                                       | 8/16 [00:05<00:05,  1.46batch/s]\u001B[A\n",
      "Generating embeddings:  56%|██████████████████████████████████████████████████████████████▍                                                | 9/16 [00:06<00:04,  1.44batch/s]\u001B[A\n",
      "Generating embeddings:  62%|████████████████████████████████████████████████████████████████████▊                                         | 10/16 [00:06<00:04,  1.42batch/s]\u001B[A\n",
      "Generating embeddings:  69%|███████████████████████████████████████████████████████████████████████████▋                                  | 11/16 [00:07<00:03,  1.44batch/s]\u001B[A\n",
      "Generating embeddings:  75%|██████████████████████████████████████████████████████████████████████████████████▌                           | 12/16 [00:08<00:02,  1.45batch/s]\u001B[A\n",
      "Generating embeddings:  81%|█████████████████████████████████████████████████████████████████████████████████████████▍                    | 13/16 [00:09<00:02,  1.44batch/s]\u001B[A\n",
      "Generating embeddings:  88%|████████████████████████████████████████████████████████████████████████████████████████████████▎             | 14/16 [00:09<00:01,  1.45batch/s]\u001B[A\n",
      "Generating embeddings:  94%|███████████████████████████████████████████████████████████████████████████████████████████████████████▏      | 15/16 [00:10<00:00,  1.40batch/s]\u001B[A\n",
      "Generating embeddings: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████| 16/16 [00:10<00:00,  1.48batch/s]\u001B[A\n",
      "INFO:lightrag:Inserting 91 vectors to relationships\n",
      "\n",
      "Generating embeddings:   0%|                                                                                                                        | 0/3 [00:00<?, ?batch/s]\u001B[A\n",
      "Generating embeddings:  33%|█████████████████████████████████████▎                                                                          | 1/3 [00:00<00:01,  1.28batch/s]\u001B[A\n",
      "Generating embeddings:  67%|██████████████████████████████████████████████████████████████████████████▋                                     | 2/3 [00:01<00:00,  1.34batch/s]\u001B[A\n",
      "Generating embeddings: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:02<00:00,  1.44batch/s]\u001B[A\n",
      "INFO:lightrag:Writing graph with 916 nodes, 163 edges\n",
      "Processing batch 1: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [18:44<00:00, 1124.09s/it]\n"
     ]
    }
   ],
   "source": [
    "rag.insert(processed_texts)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a024ea4-5d95-4311-ab1f-5505454dba1b",
   "metadata": {},
   "source": [
    "## 尝试一下"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "47058fae-3f17-4a27-b31b-e1ed5273ba3b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:07:15.150091Z",
     "iopub.status.busy": "2025-01-16T15:07:15.149911Z",
     "iopub.status.idle": "2025-01-16T15:07:15.152428Z",
     "shell.execute_reply": "2025-01-16T15:07:15.152070Z",
     "shell.execute_reply.started": "2025-01-16T15:07:15.150077Z"
    }
   },
   "outputs": [],
   "source": [
    "from lightrag import QueryParam"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e171eee9-ad79-4601-b91c-985f27533aa3",
   "metadata": {},
   "source": [
    "### 检索"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0bfe4a5-3f28-48d7-aabc-dceb8c4108e4",
   "metadata": {},
   "source": [
    "#### naive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "0578680c-b044-461e-b714-71f9db2ec906",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:07:16.270081Z",
     "iopub.status.busy": "2025-01-16T15:07:16.269520Z",
     "iopub.status.idle": "2025-01-16T15:07:16.638979Z",
     "shell.execute_reply": "2025-01-16T15:07:16.638587Z",
     "shell.execute_reply.started": "2025-01-16T15:07:16.270064Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:Truncate 2 to 2 chunks\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "，任何机构和个人不得以任何形式翻版、复\n",
      "制和发布。如引用发布，需注明出处为中国银行研究院，且不得对本报告进行有悖原意的引用、删节和修\n",
      "改。中国银行研究院保留对任何侵权行为和有悖报告原意的引用行为进行追究的权利。\n",
      "研究院\n",
      "中国北京市复兴门内大街1号\n",
      "邮编：100818\n",
      "电话：+86-10-66592780\n",
      "传真：+86-10-66594040\n",
      "--New Chunk--\n",
      "研究院\n",
      "全球经济金融展望报告\n",
      "要点2024年年报（总第57期） 报告日期：2023年12月12日\n",
      "●2023年全球经济增长动力持续回落，各国复苏分化，\n",
      "发达经济体增速明显放缓，新兴经济体整体表现稳定。\n",
      "全球贸易增长乏力，各国生产景气度逐渐回落，内需\n",
      "对经济的拉动作用减弱。欧美央行货币政策紧缩态势\n",
      "放缓，美元指数高位震荡后走弱，全球股市表现总体\n",
      "好于预期，但区域分化明显。高利率环境抑制债券融\n",
      "资需求，债券违约风险持续上升。\n",
      "●展望2024年，预计全球经济复苏将依旧疲软，主要\n",
      "经济体增长态势和货币政策走势将进一步分化。欧美\n",
      "央行大概率结束本轮紧缩货币周期，美元指数将逐步\n",
      "走弱，流向新兴经济体的跨境资本将增加。国际原油\n",
      "市场短缺格局或延续，新能源发展成为重点。\n",
      "●海湾六国经济发展与投资前景、高利率和高债务对\n",
      "美国房地产市场脆弱性的影响等热点问题值得关注。中国银行研究院\n",
      "全球经济金融研究课题组\n",
      "组长：陈卫东\n",
      "副组长：钟红\n",
      "廖淑萍\n",
      "成员：边卫红\n",
      "熊启跃\n",
      "王有鑫\n",
      "曹鸿宇\n",
      "李颖婷\n",
      "王宁远\n",
      "初晓\n",
      "章凯莉\n",
      "黄小军（纽约）\n",
      "陆晓明（纽约）\n",
      "黄承煜（纽约）\n",
      "宋达志（伦敦）\n",
      "李振龙（伦敦）\n",
      "张传捷（伦敦）\n",
      "刘冰彦（法兰克福）\n",
      "温颍坤（法兰克福）\n",
      "张明捷（法兰克福）\n",
      "王哲（东京）\n",
      "李彧（香港）\n",
      "黎永康（香港）\n",
      "联系人：王有鑫\n",
      "电话：010-66594127\n",
      "邮件：wangyouxin_hq@bank-of-china.com主要经济体GDP增速变化趋势（%）\n",
      "资料来源：IMF，中国银行研究院\n",
      "\n",
      "\n",
      "全球经济复苏疲软，货币政策取向\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='naive',\n",
    "        only_need_context=True,\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1710b398-39f4-4057-91ef-a36442ce36bc",
   "metadata": {},
   "source": [
    "#### global"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f399bd32-c18f-4359-bada-69511fa5ce95",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:07:26.789948Z",
     "iopub.status.busy": "2025-01-16T15:07:26.789768Z",
     "iopub.status.idle": "2025-01-16T15:07:29.759131Z",
     "shell.execute_reply": "2025-01-16T15:07:29.758686Z",
     "shell.execute_reply.started": "2025-01-16T15:07:26.789933Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 4 entites, 2 relations, 2 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Publication date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n",
      "\n",
      "-----Entities-----\n",
      "```csv\n",
      "id,entity,type,description,rank\n",
      "0,\"\"\"GDP\"\"\",\"\"\"EVENT\"\"\",\"\"\"Gross Domestic Product (GDP) is used as a measure to gauge global economic performance, with forecasts for growth rates.\"\"\",4\n",
      "1,\"\"\"UNITED KINGDOM\"\"\",\"\"\"GEO\"\"\",\"\"\"The United Kingdom demonstrates a decline in GDP growth compared to previous years due to various economic factors.\"\"\",1\n",
      "2,\"\"\"2024年\"\"\",\"\"\"EVENT\"\"\",\"\"\"2024年的经济预测包括欧元、英镑和日元汇率的波动，以及新兴经济体货币的变化.\"\"<SEP>\"\"在2024年这一时间点，美联储可能会调整其货币政策.\"\"|\"\">具体时间,经济预测\"\"|7\",1\n",
      "3,\"\"\"中国银行全球经济金融展望报告\"\"\",\"\"\"ORGANIZATION\"\"\",\"\"\"中国银行全球经济金融展望报告是由中国银行研究院发布的关于全球经济和金融市场预测的年度报告.\"\"\",1\n",
      "\n",
      "```\n",
      "-----Relationships-----\n",
      "```csv\n",
      "id,source,target,description,keywords,weight,rank,created_at\n",
      "0,\"\"\"GDP\"\"\",\"\"\"UNITED KINGDOM\"\"\",\"\"\"The United Kingdom's GDP is observed for its decline from 2022 levels due to a variety of economic pressures.\"\"\",\"\"\"economic indicator tracking, historical comparison\"\"\",7.0,5,\n",
      "1,\"\"\"2024年\"\"\",\"\"\"中国银行全球经济金融展望报告\"\"\",\"\"\"The China Bank's global economic and financial outlook report for 2024 provides insights into future economic scenarios.\"\"\",\"\"\"report, forecasting\"\"\",9.0,2,2025-01-16 22:28:22\n",
      "\n",
      "```\n",
      "-----Sources-----\n",
      "```csv\n",
      "id,content\n",
      "0,\"顾与展望\n",
      "（一）全球经济将在波动分化中筑底复苏\n",
      "2023年，全球经济增长动力持续回落，经济增速连续两年下降。受地缘政\n",
      "治冲突、高通胀、货币政策紧缩等因素影响，全球经济下行压力加大。预计2023\n",
      "年全球GDP增速为2.7%（市场汇率法），较2022年下降0.3个百分点。\n",
      "\n",
      "图1：全球GDP增速（%）\n",
      "资料来源：IMF，中国银行研究院\n",
      "分区域看，全球经济复苏不均衡，各国存在较大差异。发达经济体增速明\n",
      "显放缓，预计2023年增速较2022年下降1个百分点。其中，欧元区和英国经\n",
      "济增速大幅下降，美国表现好于其他发达经济体。2023年三季度，欧元区和英\n",
      "国GDP环比增速均由之前的正增长转为负增长，分别下降0.1%和0.03%；美\n",
      "国GDP环比增长折年率为4.9%，比二季度增速高2.8个百分点。新兴经济体增\n",
      "速与2022年大致持平，预计2023年增速比2022年下降0.1个百分点。其中，\n",
      "东南亚等出口型经济体增长承压，拉美、非洲等大宗商品出口国增速放缓，中\n",
      "东欧国家经济增速加快（图2）。\n",
      "\n",
      "图2：主要经济体GDP增速变化趋势（%）\n",
      "注：东盟五国包含印度尼西亚、马来西亚、菲律宾、新加坡和泰国。\n",
      "资料来源：IMF，中国银行研究院\n",
      "从生产端看，全球供应链持续恢复，但生产景气度逐渐回落。截至2023\n",
      "年10月底，纽约联储全球供应链压力指数降至有记录以来的最低值。荷兰经济\n",
      "分析局数据显示，全球工业生产量于4月触及年内低位，5-8月逐月回升，但发\n",
      "达经济体和新兴经济体分化明显（图3）。其中，主要新兴经济体工业生产指\n",
      "数普遍走高，如俄罗斯、土耳其、南非等，而发达经济体中的美国\"\n",
      "1,\"66594127\n",
      "邮件：wangyouxin_hq@bank-of-china.com主要经济体GDP增速变化趋势（%）\n",
      "资料来源：IMF，中国银行研究院\n",
      "\n",
      "\n",
      "全球经济复苏疲软，货币政策取向分化\n",
      "——中国银行全球经济金融展望报告（2024年）\n",
      "2023年，全球经济增长动力持续回落。分区域看，各国复苏存在较大差异，\n",
      "发达经济体增速明显放缓，新兴经济体增速与2022年大致持平。生产端，全球\n",
      "供应链持续恢复，但生产景气度逐渐回落。需求端，内需对经济的拉动作用逐\n",
      "渐减弱，各国国内投资和跨境投资均持续承压；全球货物贸易量指数和价格指\n",
      "数下行，主要经济体出口贸易同比增速下降。欧美央行货币政策延续收紧态势，\n",
      "但步伐整体放缓；金融体系短期资金运行发生结构性变化，“去存款化”特征\n",
      "突出。美元指数高位震荡后走弱，全球股市表现总体好于预期，但区域分化显\n",
      "著。高利率环境抑制债券融资需求，债券违约风险持续上升，美国政府债务可\n",
      "持续性问题引发市场关注。展望2024年，预计全球经济复苏将依旧疲软，主要\n",
      "经济体增长态势和货币政策将进一步分化。欧美央行大概率结束本轮加息周期，\n",
      "日本央行可能退出负利率政策，跨境资本回流美国趋势将放缓，流向新兴经济\n",
      "体的资金将增加。美元指数将逐步走弱，新兴经济体货币汇率有望回升。国际\n",
      "原油市场短缺格局或延续，新能源发展成为重点。本期报告分别对海湾六国经\n",
      "济发展与投资前景、高利率和高债务对美国房地产市场脆弱性的影响两个专题\n",
      "展开分析。\n",
      "一、全球经济回顾与展望\n",
      "（一）全球经济将在波动分化中筑底复苏\n",
      "2023年，全球经济增长动力持续回落，经济增速连续两年下降。受地缘政\n",
      "治冲突、高通\"\n",
      "\n",
      "```\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='global',\n",
    "        only_need_context=True,\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bb9ec1c-56ce-4149-836c-f976d39a39a7",
   "metadata": {},
   "source": [
    "#### hybrid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c622d165-4fa1-4df3-9efb-d32f9a4f52c8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:07:37.757927Z",
     "iopub.status.busy": "2025-01-16T15:07:37.757723Z",
     "iopub.status.idle": "2025-01-16T15:07:38.618886Z",
     "shell.execute_reply": "2025-01-16T15:07:38.618298Z",
     "shell.execute_reply.started": "2025-01-16T15:07:37.757913Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "WARNING:lightrag:low_level_keywords is empty, switching from hybrid mode to global mode\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 4 entites, 2 relations, 2 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Publication date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n",
      "\n",
      "-----Entities-----\n",
      "```csv\n",
      "id,entity,type,description,rank\n",
      "0,\"\"\"GDP\"\"\",\"\"\"EVENT\"\"\",\"\"\"Gross Domestic Product (GDP) is used as a measure to gauge global economic performance, with forecasts for growth rates.\"\"\",4\n",
      "1,\"\"\"UNITED KINGDOM\"\"\",\"\"\"GEO\"\"\",\"\"\"The United Kingdom demonstrates a decline in GDP growth compared to previous years due to various economic factors.\"\"\",1\n",
      "2,\"\"\"2024年\"\"\",\"\"\"EVENT\"\"\",\"\"\"2024年的经济预测包括欧元、英镑和日元汇率的波动，以及新兴经济体货币的变化.\"\"<SEP>\"\"在2024年这一时间点，美联储可能会调整其货币政策.\"\"|\"\">具体时间,经济预测\"\"|7\",1\n",
      "3,\"\"\"中国银行全球经济金融展望报告\"\"\",\"\"\"ORGANIZATION\"\"\",\"\"\"中国银行全球经济金融展望报告是由中国银行研究院发布的关于全球经济和金融市场预测的年度报告.\"\"\",1\n",
      "\n",
      "```\n",
      "-----Relationships-----\n",
      "```csv\n",
      "id,source,target,description,keywords,weight,rank,created_at\n",
      "0,\"\"\"GDP\"\"\",\"\"\"UNITED KINGDOM\"\"\",\"\"\"The United Kingdom's GDP is observed for its decline from 2022 levels due to a variety of economic pressures.\"\"\",\"\"\"economic indicator tracking, historical comparison\"\"\",7.0,5,\n",
      "1,\"\"\"2024年\"\"\",\"\"\"中国银行全球经济金融展望报告\"\"\",\"\"\"The China Bank's global economic and financial outlook report for 2024 provides insights into future economic scenarios.\"\"\",\"\"\"report, forecasting\"\"\",9.0,2,2025-01-16 22:28:22\n",
      "\n",
      "```\n",
      "-----Sources-----\n",
      "```csv\n",
      "id,content\n",
      "0,\"顾与展望\n",
      "（一）全球经济将在波动分化中筑底复苏\n",
      "2023年，全球经济增长动力持续回落，经济增速连续两年下降。受地缘政\n",
      "治冲突、高通胀、货币政策紧缩等因素影响，全球经济下行压力加大。预计2023\n",
      "年全球GDP增速为2.7%（市场汇率法），较2022年下降0.3个百分点。\n",
      "\n",
      "图1：全球GDP增速（%）\n",
      "资料来源：IMF，中国银行研究院\n",
      "分区域看，全球经济复苏不均衡，各国存在较大差异。发达经济体增速明\n",
      "显放缓，预计2023年增速较2022年下降1个百分点。其中，欧元区和英国经\n",
      "济增速大幅下降，美国表现好于其他发达经济体。2023年三季度，欧元区和英\n",
      "国GDP环比增速均由之前的正增长转为负增长，分别下降0.1%和0.03%；美\n",
      "国GDP环比增长折年率为4.9%，比二季度增速高2.8个百分点。新兴经济体增\n",
      "速与2022年大致持平，预计2023年增速比2022年下降0.1个百分点。其中，\n",
      "东南亚等出口型经济体增长承压，拉美、非洲等大宗商品出口国增速放缓，中\n",
      "东欧国家经济增速加快（图2）。\n",
      "\n",
      "图2：主要经济体GDP增速变化趋势（%）\n",
      "注：东盟五国包含印度尼西亚、马来西亚、菲律宾、新加坡和泰国。\n",
      "资料来源：IMF，中国银行研究院\n",
      "从生产端看，全球供应链持续恢复，但生产景气度逐渐回落。截至2023\n",
      "年10月底，纽约联储全球供应链压力指数降至有记录以来的最低值。荷兰经济\n",
      "分析局数据显示，全球工业生产量于4月触及年内低位，5-8月逐月回升，但发\n",
      "达经济体和新兴经济体分化明显（图3）。其中，主要新兴经济体工业生产指\n",
      "数普遍走高，如俄罗斯、土耳其、南非等，而发达经济体中的美国\"\n",
      "1,\"66594127\n",
      "邮件：wangyouxin_hq@bank-of-china.com主要经济体GDP增速变化趋势（%）\n",
      "资料来源：IMF，中国银行研究院\n",
      "\n",
      "\n",
      "全球经济复苏疲软，货币政策取向分化\n",
      "——中国银行全球经济金融展望报告（2024年）\n",
      "2023年，全球经济增长动力持续回落。分区域看，各国复苏存在较大差异，\n",
      "发达经济体增速明显放缓，新兴经济体增速与2022年大致持平。生产端，全球\n",
      "供应链持续恢复，但生产景气度逐渐回落。需求端，内需对经济的拉动作用逐\n",
      "渐减弱，各国国内投资和跨境投资均持续承压；全球货物贸易量指数和价格指\n",
      "数下行，主要经济体出口贸易同比增速下降。欧美央行货币政策延续收紧态势，\n",
      "但步伐整体放缓；金融体系短期资金运行发生结构性变化，“去存款化”特征\n",
      "突出。美元指数高位震荡后走弱，全球股市表现总体好于预期，但区域分化显\n",
      "著。高利率环境抑制债券融资需求，债券违约风险持续上升，美国政府债务可\n",
      "持续性问题引发市场关注。展望2024年，预计全球经济复苏将依旧疲软，主要\n",
      "经济体增长态势和货币政策将进一步分化。欧美央行大概率结束本轮加息周期，\n",
      "日本央行可能退出负利率政策，跨境资本回流美国趋势将放缓，流向新兴经济\n",
      "体的资金将增加。美元指数将逐步走弱，新兴经济体货币汇率有望回升。国际\n",
      "原油市场短缺格局或延续，新能源发展成为重点。本期报告分别对海湾六国经\n",
      "济发展与投资前景、高利率和高债务对美国房地产市场脆弱性的影响两个专题\n",
      "展开分析。\n",
      "一、全球经济回顾与展望\n",
      "（一）全球经济将在波动分化中筑底复苏\n",
      "2023年，全球经济增长动力持续回落，经济增速连续两年下降。受地缘政\n",
      "治冲突、高通\"\n",
      "\n",
      "```\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='hybrid',\n",
    "        only_need_context=True,\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e8f1f12-2e55-4908-9f7e-427595f651cd",
   "metadata": {},
   "source": [
    "#### local"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "a4b51a9c-27c1-4ce7-a9fe-2c5d5562fce1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:07:43.924138Z",
     "iopub.status.busy": "2025-01-16T15:07:43.923961Z",
     "iopub.status.idle": "2025-01-16T15:07:44.792609Z",
     "shell.execute_reply": "2025-01-16T15:07:44.792147Z",
     "shell.execute_reply.started": "2025-01-16T15:07:43.924123Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "WARNING:lightrag:low_level_keywords is empty, switching from local mode to global mode\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 4 entites, 2 relations, 2 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Release date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n",
      "\n",
      "-----Entities-----\n",
      "```csv\n",
      "id,entity,type,description,rank\n",
      "0,\"\"\"2023年\"\"\",\"\"\"GEO\"\"\",\"\"\"2023年被描述为全球经济趋势的一年，包括GDP增速、区域复苏、供应链恢复等指标的分析。\"\"<SEP>\"\"时间点描述，具体到2023年，包括贷款需求下降、新发放量下降以及资产价格变化的情况。\"\"\",3\n",
      "1,\"\"\"新发放量下降\"\"\",\"\"\"UNKNOWN\"\"\",\"\"\"特定时间点的新发放量变化，表明市场活动和需求的变化。\"\"\",1\n",
      "2,\"\"\"2024年\"\"\",\"\"\"EVENT\"\"\",\"\"\"2024年的经济预测包括欧元、英镑和日元汇率的波动，以及新兴经济体货币的变化.\"\"<SEP>\"\"在2024年这一时间点，美联储可能会调整其货币政策.\"\"|\"\">具体时间,经济预测\"\"|7\",1\n",
      "3,\"\"\"中国银行全球经济金融展望报告\"\"\",\"\"\"ORGANIZATION\"\"\",\"\"\"中国银行全球经济金融展望报告是由中国银行研究院发布的关于全球经济和金融市场预测的年度报告.\"\"\",1\n",
      "\n",
      "```\n",
      "-----Relationships-----\n",
      "```csv\n",
      "id,source,target,description,keywords,weight,rank,created_at\n",
      "0,\"\"\"2023年\"\"\",\"\"\"新发放量下降\"\"\",\"\"\"特定时间点的新发放量变化，表明市场活动和需求的变化。\"\"\",\"\"\"时间与事件关系\"\"\",6.0,4,\n",
      "1,\"\"\"2024年\"\"\",\"\"\"中国银行全球经济金融展望报告\"\"\",\"\"\"The China Bank's global economic and financial outlook report for 2024 provides insights into future economic scenarios.\"\"\",\"\"\"report, forecasting\"\"\",9.0,2,2025-01-16 22:28:22\n",
      "\n",
      "```\n",
      "-----Sources-----\n",
      "```csv\n",
      "id,content\n",
      "0,\"到期，35%以上将\n",
      "在2030年之后到期。由于许多办公楼在建，未来空置率将进一步攀升，增加了\n",
      "市场的不确定性。商业房地产市场脆弱性对金融风险的传导路径主要包括以下\n",
      "几个方面。\n",
      "第一，需求减少导致价格下降。美联储调查显示，大多数银行报告，贷款\n",
      "需求在下降，2023年以来商业房地产贷款月度同比增幅下滑。据预测，2023年\n",
      "\n",
      "该类贷款新发放量将同比下降46%。同时，商业房地产抵押证券CMBS新发行\n",
      "也出现停滞。商业房地产价格指数CPPI已从2022年5月历史峰值的155，下降\n",
      "至2023年11月的125，虽高于次贷危机时期的历史低点63，但其降幅接近次贷\n",
      "危机时期的表现。\n",
      "第二，金融资产质量开始下降。银行业商业房地产贷款拖欠率季度平均值\n",
      "从2022年三季度的0.7%上升至2023年二季度的0.8%。对市场更敏感的CMBS\n",
      "拖欠率则从2023年5月的3%左右持续上升到10月的4.63%。其中，办公楼宇\n",
      "部分从2022年12月的2%持续上升到5.75%。2023年中旬，商业房地产陷入困\n",
      "境的资产余额连续四个季度上升至718亿美元。\n",
      "第三，未来金融风险可能上升。2023-2024年美国商业房地产将有9000亿\n",
      "美元债务到期，大约占该类债务的16%。其中，办公楼相关债务到期日相对集\n",
      "中，2023-2024年可能超2000亿美元。债务集中到期、利率上升、贷款条件收\n",
      "紧叠加价格下降将使债务人再融资成本、难度和风险上升。\n",
      "第四，中小型银行风险敞口较高。银行商业房地产贷款主要采取表内模式，\n",
      "且中小型银行占比达70%，高于次贷危机时的55%。该类贷款在中小银行资产\n",
      "中占比达29%，高于大型银行的6.4%，风险敞口更集中。\n",
      "（三）\"\n",
      "1,\"66594127\n",
      "邮件：wangyouxin_hq@bank-of-china.com主要经济体GDP增速变化趋势（%）\n",
      "资料来源：IMF，中国银行研究院\n",
      "\n",
      "\n",
      "全球经济复苏疲软，货币政策取向分化\n",
      "——中国银行全球经济金融展望报告（2024年）\n",
      "2023年，全球经济增长动力持续回落。分区域看，各国复苏存在较大差异，\n",
      "发达经济体增速明显放缓，新兴经济体增速与2022年大致持平。生产端，全球\n",
      "供应链持续恢复，但生产景气度逐渐回落。需求端，内需对经济的拉动作用逐\n",
      "渐减弱，各国国内投资和跨境投资均持续承压；全球货物贸易量指数和价格指\n",
      "数下行，主要经济体出口贸易同比增速下降。欧美央行货币政策延续收紧态势，\n",
      "但步伐整体放缓；金融体系短期资金运行发生结构性变化，“去存款化”特征\n",
      "突出。美元指数高位震荡后走弱，全球股市表现总体好于预期，但区域分化显\n",
      "著。高利率环境抑制债券融资需求，债券违约风险持续上升，美国政府债务可\n",
      "持续性问题引发市场关注。展望2024年，预计全球经济复苏将依旧疲软，主要\n",
      "经济体增长态势和货币政策将进一步分化。欧美央行大概率结束本轮加息周期，\n",
      "日本央行可能退出负利率政策，跨境资本回流美国趋势将放缓，流向新兴经济\n",
      "体的资金将增加。美元指数将逐步走弱，新兴经济体货币汇率有望回升。国际\n",
      "原油市场短缺格局或延续，新能源发展成为重点。本期报告分别对海湾六国经\n",
      "济发展与投资前景、高利率和高债务对美国房地产市场脆弱性的影响两个专题\n",
      "展开分析。\n",
      "一、全球经济回顾与展望\n",
      "（一）全球经济将在波动分化中筑底复苏\n",
      "2023年，全球经济增长动力持续回落，经济增速连续两年下降。受地缘政\n",
      "治冲突、高通\"\n",
      "\n",
      "```\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='local',\n",
    "        only_need_context=True,\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8937d6b-ead9-4021-a42f-0443f52b4e8f",
   "metadata": {},
   "source": [
    "### 问答"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a6e2d82d-0ed8-4009-b518-20f457b2ec8d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:09:22.810811Z",
     "iopub.status.busy": "2025-01-16T15:09:22.810568Z",
     "iopub.status.idle": "2025-01-16T15:09:23.072765Z",
     "shell.execute_reply": "2025-01-16T15:09:23.072308Z",
     "shell.execute_reply.started": "2025-01-16T15:09:22.810797Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这份报告是在2023年发布的。文中提到的具体时间点包括：\n",
      "\n",
      "1. 中国银行研究院在2023年的报告中分析了美国经济的情况。\n",
      "2. 在报告中讨论了2023年的全球GDP增速预期，这一数据来自国际货币基金组织（IMF）和中国银行研究院的预测。\n",
      "3. 说明沙特阿拉伯、埃及、阿联酋等国在2022年加入了金砖国家组织，并在2023年继续合作，这表明报告至少覆盖了2022年至2023年的信息。\n",
      "\n",
      "通过这些细节可以推断出该报告的发布日期应该是在2023年。具体到哪一天则未直接明确给出，但基于其内含的分析和数据，可以合理推测报告可能是于当年某个时间点进行发布或最终定稿的。\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='global',\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "729679ca-1091-4c9f-ab28-24f2afc83143",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:09:31.342980Z",
     "iopub.status.busy": "2025-01-16T15:09:31.342781Z",
     "iopub.status.idle": "2025-01-16T15:09:42.530189Z",
     "shell.execute_reply": "2025-01-16T15:09:42.529779Z",
     "shell.execute_reply.started": "2025-01-16T15:09:31.342966Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "WARNING:lightrag:low_level_keywords is empty, switching from local mode to global mode\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 4 entites, 2 relations, 2 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Publication date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n",
      "中国银行全球经济金融展望报告（2024年）的发布时间记录在数据表中，具体时间为2025年1月16日。这一报告由中国的银行业研究院负责发布，内容包含了关于全球经济发展和金融市场预测的详细信息。\n",
      "\n",
      "从提供的数据可以了解到，在过去的一年内，全球经济增长动力持续减弱，经济增速出现了连续两年下降的趋势。报告提到了一些关键点：\n",
      "\n",
      "- 发达经济体的增长速度明显放缓。\n",
      "- 新兴经济体的增长与2022年大致持平，但也有一定幅度的减速。\n",
      "- 全球供应链持续恢复，但生产活动的景气度正在逐渐回落。\n",
      "\n",
      "在需求端的表现上，报告指出内需对经济增长的拉动作用逐渐减弱，并且各国国内投资和跨境投资均面临压力。全球货物贸易量指数和价格指数下行，主要经济体出口增速下降。欧美央行的货币政策继续收紧，尽管步伐已经有所放缓；金融体系中短期资金运行出现了结构性变化，“去存款化”现象明显。\n",
      "\n",
      "对于货币市场而言，报告指出美元指数在高位震荡后开始走弱，全球股市总体表现较好但存在区域差异。高利率环境抑制了债券融资需求，并导致债券违约风险持续上升。美国政府债务的可持续性问题也引起了市场的关注。\n",
      "\n",
      "展望2024年，全球经济预计将继续保持疲软的状态，主要经济体的增长态势和货币政策将呈现进一步分化的特点。报告预测欧美央行可能会结束本轮加息周期，日本央行可能退出负利率政策，跨境资本回流至美国的趋势会放缓，更多资金将流向新兴经济体。美元指数预计将逐步走弱，这有望促进新兴经济体货币汇率的回升。\n",
      "\n",
      "国际原油市场可能继续保持短缺格局，而新能源发展则被列为全球关注的重点之一。报告通过具体分析海湾六国经济发展与投资前景以及高利率和高债务对美国房地产市场的脆弱性影响这两个专题，为读者提供了更深入的理解。\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='local',\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "cbbe4abb-fc72-4fa1-89be-59d3672e1e1f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:09:45.776408Z",
     "iopub.status.busy": "2025-01-16T15:09:45.776229Z",
     "iopub.status.idle": "2025-01-16T15:09:50.822557Z",
     "shell.execute_reply": "2025-01-16T15:09:50.822089Z",
     "shell.execute_reply.started": "2025-01-16T15:09:45.776393Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "WARNING:lightrag:low_level_keywords is empty, switching from hybrid mode to global mode\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 4 entites, 2 relations, 2 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Release date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n",
      "中国银行全球经济金融展望报告是在2024年的某个时间点发布的。该报告提供了对未来全球经济发展和金融市场预测的见解，包括对欧元、英镑和日元汇率波动以及新兴经济体货币变化的分析，并指出在2024年期间美联储可能会调整其货币政策。\n",
      "\n",
      "根据提供的信息，无法精确确定这份报告的具体发布日期。通常，经济展望报告会在新一年开始时发布，用来预测未来一年全球经济和金融市场的走势，因此可以合理推测中国银行全球金融展望报告是在2024年初发布的。\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='hybrid',\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "a217d149-f507-416f-857a-56726eb41570",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:09:53.243697Z",
     "iopub.status.busy": "2025-01-16T15:09:53.243482Z",
     "iopub.status.idle": "2025-01-16T15:10:02.346818Z",
     "shell.execute_reply": "2025-01-16T15:10:02.346277Z",
     "shell.execute_reply.started": "2025-01-16T15:09:53.243682Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:Truncate 2 to 2 chunks\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "报告《全球经济金融展望报告》的发布日期为2023年12月12日。这是由中国银行研究院在这一日期发布的年度经济报告，旨在提供对全球经济增长、金融市场变动以及宏观经济政策趋势的深入分析和预测。报告中的数据和观点反映了截止到该发布时间点的世界经济状况与前景展望。\n",
      "\n",
      "报告指出，在已经过去的2023年里，全球经济复苏动力持续减弱，特别是在不同国家和地区之间呈现出明显的分化现象：发达经济体的增长速度显著放缓，而新兴经济体的整体表现相对稳定。全球贸易活动增长乏力，生产领域景气度逐渐下降，内需对经济增长的推动作用也在减退。\n",
      "\n",
      "对于即将到来的2024年，报告预测全球经济复苏将继续保持疲软态势，主要经济体之间的增长趋势和货币政策走势将进一步分化。预计欧美央行将结束本轮紧缩货币周期，美元指数逐步走弱，并可能看到更多资本流向新兴市场经济体。同时，国际原油市场可能继续处于短缺状态，新能源发展预计将占据重要地位。\n",
      "\n",
      "报告还特别关注了海湾六国的经济发展与投资前景、高利率和高债务对美国房地产市场的潜在影响等热点问题。这份报告集结了中国银行研究院专家团队的深入研究和分析，涵盖多个经济领域的动态与挑战，旨在为决策者、投资者以及相关行业提供参考依据。\n",
      "\n",
      "报告的联系人是王有鑫先生，他负责与外界沟通，并能解答关于这份报告的任何疑问。如果有需要进一步了解或讨论的问题，请通过提供的电话号码010-66594127或者邮件wangyouxin_hq@bank-of-china.com与他取得联系。\n",
      "\n",
      "附录中提供了一份主要经济体GDP增速变化趋势的数据来源，该数据来自国际货币基金组织（IMF）和中国银行研究院的综合分析。这些数据对于理解和评估全球经济动态至关重要，它们为报告中的其他预测和分析提供了坚实的基础。\n"
     ]
    }
   ],
   "source": [
    "print(rag.query(\n",
    "    '报告的发布日期是什么时候？',\n",
    "    QueryParam(\n",
    "        mode='naive',\n",
    "        top_k=2\n",
    "    )\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fcd6e405-1220-4e75-9e83-8d2e7d07a7a6",
   "metadata": {},
   "source": [
    "# 批量预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "2088a7e1-8c9f-480a-8e00-e29c8bcf31f5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:10:08.060059Z",
     "iopub.status.busy": "2025-01-16T15:10:08.059885Z",
     "iopub.status.idle": "2025-01-16T15:10:08.165499Z",
     "shell.execute_reply": "2025-01-16T15:10:08.165019Z",
     "shell.execute_reply.started": "2025-01-16T15:10:08.060046Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from tqdm.auto import tqdm\n",
    "\n",
    "qa_df = pd.read_excel(os.path.join(preprocess_output_dir, 'question_answer.xlsx'))\n",
    "prediction_df = qa_df[qa_df['dataset'] == 'test'][['uuid', 'question', 'qa_type', 'answer']].rename(columns={'answer': 'ref_answer'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "6047fa19-92eb-4f4b-9e55-af47bc01244c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-16T15:10:08.397240Z",
     "iopub.status.busy": "2025-01-16T15:10:08.396842Z",
     "iopub.status.idle": "2025-01-16T15:10:08.401908Z",
     "shell.execute_reply": "2025-01-16T15:10:08.401074Z",
     "shell.execute_reply.started": "2025-01-16T15:10:08.397224Z"
    }
   },
   "outputs": [],
   "source": [
    "save_path = os.path.join(expr_dir, 'predictions.pkl')\n",
    "\n",
    "if os.path.exists(save_path):\n",
    "    pred_dfs = pickle.load(open(save_path, 'rb'))\n",
    "else:\n",
    "    pred_dfs = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "c2d267c4-c71c-45ae-a6bf-232831350000",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:01:19.009503Z",
     "iopub.status.busy": "2025-01-17T01:01:19.009079Z",
     "iopub.status.idle": "2025-01-17T01:01:19.012587Z",
     "shell.execute_reply": "2025-01-17T01:01:19.012093Z",
     "shell.execute_reply.started": "2025-01-17T01:01:19.009486Z"
    }
   },
   "outputs": [],
   "source": [
    "def predict(pred_df, mode):\n",
    "    pred_df = pred_df.copy()\n",
    "    \n",
    "    answers = []\n",
    "    for idx, row in tqdm(prediction_df.iterrows(), total=len(prediction_df), desc=f\"mode={mode}\"):\n",
    "        answer = rag.query(\n",
    "            row['question'],\n",
    "            QueryParam(\n",
    "                mode=mode,\n",
    "                top_k=4,\n",
    "                max_token_for_text_unit=500,\n",
    "                max_token_for_global_context=8000,\n",
    "                max_token_for_local_context=8000,\n",
    "            )\n",
    "        )\n",
    "        answers.append(answer)\n",
    "    pred_df['gen_answer'] = answers\n",
    "    \n",
    "    return pred_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "da094809-e544-4c34-bc70-ed7649c4c084",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:01:20.389792Z",
     "iopub.status.busy": "2025-01-17T01:01:20.389525Z",
     "iopub.status.idle": "2025-01-17T01:04:29.497822Z",
     "shell.execute_reply": "2025-01-17T01:04:29.497315Z",
     "shell.execute_reply.started": "2025-01-17T01:01:20.389776Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "83064d41722348e383de5ebaaaeb1e35",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "mode=global:   0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a5eb024ff08a4e06a9d475a88acf1b48",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "mode=hybrid:   0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "WARNING:lightrag:low_level_keywords is empty, switching from hybrid mode to global mode\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 8 entites, 4 relations, 1 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Publication date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "INFO:lightrag:Using hybrid mode for query processing\n",
      "INFO:lightrag:Local query uses 4 entites, 0 relations, 1 text units\n",
      "INFO:lightrag:Global query uses 8 entites, 4 relations, 1 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"欧洲央行\", \"暂停加息\", \"货币政策\"],\n",
      "  \"low_level_keywords\": [\"利率\", \"经济环境\", \"市场预期\"]\n",
      "}\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5b638d7d387a494ca5aaec8af4232e5b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "mode=local:   0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "INFO:lightrag:Using local mode for query processing\n",
      "INFO:lightrag:Local query uses 4 entites, 5 relations, 1 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Publishing agency\"],\n",
      "  \"low_level_keywords\": [\"Institution\", \"Organization\", \"Company\"]\n",
      "}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "WARNING:lightrag:low_level_keywords is empty, switching from local mode to global mode\n",
      "INFO:lightrag:Using global mode for query processing\n",
      "INFO:lightrag:Global query uses 8 entites, 4 relations, 1 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Report\", \"Publication date\"],\n",
      "  \"low_level_keywords\": []\n",
      "}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:lightrag:kw_prompt result:\n",
      "INFO:lightrag:Using local mode for query processing\n",
      "INFO:lightrag:Local query uses 4 entites, 0 relations, 1 text units\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"high_level_keywords\": [\"Eurozone\", \"PMI (Purchasing Managers' Index)\", \"Employment\"],\n",
      "  \"low_level_keywords\": [\"October\", \"Index\"]\n",
      "}\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "98973829f5a8431cbb0b4478ba19eb9b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "mode=naive:   0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pickle\n",
    "\n",
    "for mode in ['global', 'hybrid', 'local', 'naive']:\n",
    "    pred_dfs[mode] = predict(prediction_df, mode)\n",
    "    pickle.dump(pred_dfs, open(save_path, 'wb'))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab68318e-e1c5-4d26-a939-5b42efb3cf4b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-11-12T07:12:57.157657Z",
     "iopub.status.busy": "2024-11-12T07:12:57.156875Z",
     "iopub.status.idle": "2024-11-12T07:12:57.166484Z",
     "shell.execute_reply": "2024-11-12T07:12:57.164085Z",
     "shell.execute_reply.started": "2024-11-12T07:12:57.157586Z"
    }
   },
   "source": [
    "# 评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "90b99dc1-14d6-4557-9e7c-320ac0fff7f8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:06:09.123800Z",
     "iopub.status.busy": "2025-01-17T01:06:09.123619Z",
     "iopub.status.idle": "2025-01-17T01:06:09.138622Z",
     "shell.execute_reply": "2025-01-17T01:06:09.138118Z",
     "shell.execute_reply.started": "2025-01-17T01:06:09.123785Z"
    }
   },
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "import time\n",
    "\n",
    "judge_llm = ChatOpenAI(\n",
    "    api_key=os.environ['LLM_API_KEY'],\n",
    "    base_url=os.environ['LLM_BASE_URL'],\n",
    "    model_name='qwen2-72b-instruct',\n",
    "    temperature=0\n",
    ")\n",
    "\n",
    "def evaluate(pred_df):\n",
    "    \"\"\"\n",
    "    对预测结果进行打分\n",
    "    :param pred_df: 预测结果，需要包含问题，参考答案，生成的答案，列名分别为question, ref_answer, gen_answer\n",
    "    :return 打分模型原始返回结果\n",
    "    \"\"\"\n",
    "    prompt_tmpl = \"\"\"\n",
    "你是一个经济学博士，现在我有一系列问题，有一个助手已经对这些问题进行了回答，你需要参照参考答案，评价这个助手的回答是否正确，仅回复“是”或“否”即可，不要带其他描述性内容或无关信息。\n",
    "问题：\n",
    "<question>\n",
    "{{question}}\n",
    "</question>\n",
    "\n",
    "参考答案：\n",
    "<ref_answer>\n",
    "{{ref_answer}}\n",
    "</ref_answer>\n",
    "\n",
    "助手回答：\n",
    "<gen_answer>\n",
    "{{gen_answer}}\n",
    "</gen_answer>\n",
    "请评价：\n",
    "    \"\"\"\n",
    "    results = []\n",
    "\n",
    "    for _, row in tqdm(pred_df.iterrows(), total=len(pred_df)):\n",
    "        question = row['question']\n",
    "        ref_answer = row['ref_answer']\n",
    "        gen_answer = row['gen_answer']\n",
    "\n",
    "        prompt = prompt_tmpl.replace('{{question}}', question).replace('{{ref_answer}}', str(ref_answer)).replace('{{gen_answer}}', gen_answer).strip()\n",
    "        \n",
    "        retry_count = 3\n",
    "        result = ''\n",
    "        \n",
    "        while retry_count > 0:\n",
    "            try:\n",
    "                result = judge_llm.invoke(prompt).content\n",
    "                break\n",
    "            except Exception as e:\n",
    "                retry_count -= 1\n",
    "                sleeping_seconds = 2 ** (4 - retry_count)\n",
    "                print(f\"query={question}, error={e}, sleeping={sleeping_seconds}, remaining retry count={retry_count}\")\n",
    "                \n",
    "                time.sleep(sleeping_seconds)\n",
    "        \n",
    "        results.append(result)\n",
    "\n",
    "        time.sleep(1)\n",
    "    return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "fd5aebd4-b557-4e20-8699-7fe0f2fa8d16",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:09:05.019865Z",
     "iopub.status.busy": "2025-01-17T01:09:05.019663Z",
     "iopub.status.idle": "2025-01-17T01:19:41.875546Z",
     "shell.execute_reply": "2025-01-17T01:19:41.875040Z",
     "shell.execute_reply.started": "2025-01-17T01:09:05.019851Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "24b7904f45c9448998ea108dcf0dcdf5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mode=global raw_score unique: ['否' '是'], accuracy=0.1\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7e074c1c4d104df3bd771da805bd2336",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mode=hybrid raw_score unique: ['否' '是'], accuracy=0.11\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "df73ea74738441ac9bab822f510130cc",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mode=local raw_score unique: ['否' '是'], accuracy=0.09\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "cfa775ca19f541f19c57b8545b95ad06",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/100 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mode=naive raw_score unique: ['否' '是'], accuracy=0.24\n"
     ]
    }
   ],
   "source": [
    "metrics = []\n",
    "\n",
    "for mode in pred_dfs:\n",
    "    pred_df = pred_dfs[mode]\n",
    "    pred_df['raw_score'] = evaluate(pred_df)\n",
    "    pred_df['score'] = (pred_df['raw_score'] == '是').astype(int)\n",
    "    print(f\"mode={mode} raw_score unique: {pred_df['raw_score'].unique()}, accuracy={pred_df['score'].mean()}\")\n",
    "\n",
    "    metrics.append({\n",
    "        'mode': mode,\n",
    "        'accuracy': pred_df['score'].mean()\n",
    "    })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "f403c2d6-dacf-4eb8-a092-37b06ec942cb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:20:15.846639Z",
     "iopub.status.busy": "2025-01-17T01:20:15.846459Z",
     "iopub.status.idle": "2025-01-17T01:20:16.006614Z",
     "shell.execute_reply": "2025-01-17T01:20:16.006241Z",
     "shell.execute_reply.started": "2025-01-17T01:20:15.846625Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving to ../experiments/kg_v01_lightrag/eval_dfs.pkl\n"
     ]
    }
   ],
   "source": [
    "save_path = os.path.join(expr_dir, 'eval_dfs.pkl')\n",
    "\n",
    "if not os.path.exists(save_path):\n",
    "    print(f'saving to {save_path}')\n",
    "    pickle.dump(pred_dfs, open(save_path, 'wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "7c3b9c1b-b391-46ed-9a57-52b1873e48d1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:20:16.126549Z",
     "iopub.status.busy": "2025-01-17T01:20:16.126235Z",
     "iopub.status.idle": "2025-01-17T01:20:16.132248Z",
     "shell.execute_reply": "2025-01-17T01:20:16.131887Z",
     "shell.execute_reply.started": "2025-01-17T01:20:16.126532Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mode</th>\n",
       "      <th>accuracy</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>global</td>\n",
       "      <td>0.10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>hybrid</td>\n",
       "      <td>0.11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>local</td>\n",
       "      <td>0.09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>naive</td>\n",
       "      <td>0.24</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     mode  accuracy\n",
       "0  global      0.10\n",
       "1  hybrid      0.11\n",
       "2   local      0.09\n",
       "3   naive      0.24"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metrics_df = pd.DataFrame(metrics)\n",
    "metrics_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "8ec267b9-486d-401b-9574-aa8409a8335b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-01-17T01:20:25.681720Z",
     "iopub.status.busy": "2025-01-17T01:20:25.681382Z",
     "iopub.status.idle": "2025-01-17T01:20:25.841637Z",
     "shell.execute_reply": "2025-01-17T01:20:25.841224Z",
     "shell.execute_reply.started": "2025-01-17T01:20:25.681701Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='mode', ylabel='accuracy'>"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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ubN2797tihoBAABcyukAdPHiRb3//vvq1auXGjVqpM8++0wLFixQXl6eDhw4oEaNGmnAgAGurBUAAMAlnHob/OjRo/XOO+/Isiw99thjmjVrllq1amU/XqdOHc2ZM0chISEuKxQAAMBVnApAe/bs0Wuvvab+/ftf8SskAgIC9OWXX95UcQAAABXBqQD026+vuOLANWooNpbPUgAAAFWPU2uAUlJStGTJksvalyxZopkzZ950UQAAABXJqQD097//Xffcc89l7ffee68WLVp000UBAABUJKcCUG5ubrnfrn7bbbfp+PHjN10UAABARXIqAIWFhWnjxo2XtW/cuJF3fgEAgCrPqUXQI0aM0Lhx43Tx4kV17dpV0q8Lo5977jk988wzLi0QAADA1ZwKQOPHj9fp06c1cuRI+/d/+fj4aMKECUpOTnZpgQAAAK7mVACy2WyaOXOmJk2apKysLNWqVUvNmjW74mcCAQAAVCVOBaBL6tatq44dO7qqFgAAgErhdADasmWL3n33XWVnZ9sfg13yz3/+86YLAwAAqChOvQts1apVuv/++5WVlaUPP/xQFy9e1O7du7V+/Xr5+vq6ukYAAACXcioAvfTSS3r55Zf1ySefyMvLS6+88or27t2rRx99VHfeeaerawQAAHAppwLQTz/9pIcffliS5OXlpeLiYtlsNj399NN64403XFogAACAqzkVgPz8/HTu3DlJUmhoqHbt2iVJys/P1/nz511XHQAAQAVwahH0gw8+qHXr1ql169YaMGCAxo4dq/Xr12vdunXq1q2bq2sEAABwKacC0IIFC/Tzzz9Lkv7f//t/qlmzpr799ls98sgjmjhxoksLBAAAcLUbDkC//PKL/vWvfyk+Pl6S5OHhoeeff97lhQEAAFSUG14DVKNGDf3lL3+x3wECAACobpxaBB0VFaUdO3a4uBQAAIDK4dQaoJEjRyopKUk5OTmKjIxUnTp1HI5HRES4pDgAAICK4FQAGjRokCRpzJgx9jabzSbLsmSz2VRaWuqa6gAAACqAUwHo0KFDrq4DAACg0jgVgBo1auTqOgAAACqNUwFoxYoVVz2ekJDgVDEAAACVwakANHbsWIf9ixcv6vz58/Ly8lLt2rUJQAAAoEpz6m3wZ8+eddiKioq0b98+derUSe+8846rawQAAHAppwJQeZo1a6YZM2ZcdncIAACgqnFZAJJ+/ZToY8eOuXJIAAAAl3NqDdDHH3/ssG9Zlo4fP64FCxbogQcecElhAAAAFcWpANSvXz+HfZvNpttuu01du3bV3LlzXVEXAABAhXEqAJWVlbm6DgAAgErj0jVAAAAA1YFTAeiRRx7RzJkzL2ufNWuWBgwYcNNFAQAAVCSnAtBXX32lXr16Xdbes2dPffXVVzddFAAAQEVyKgAVFRXJy8vrsvaaNWuqsLDwposCAACoSE4FoNatW2v16tWXta9atUotW7a86aIAAAAqklPvAps0aZL69++vn376SV27dpUkpaWl6Z133tF7773n0gIBAABczakA1KdPH61Zs0YvvfSS3n//fdWqVUsRERH64osvFBsb6+oaAQAAXMqpACRJDz/8sB5++GFX1gIAAFApnFoD9N133ykzM/Oy9szMTG3ZsuWmiwIAAKhITgWgp556Sjk5OZe1Hz16VE899dRNFwUAAFCRnApAe/bsUfv27S9rb9eunfbs2XPTRQEAAFQkpwKQt7e38vLyLms/fvy4atRwelkRAABApXAqAHXv3l3JyckqKCiwt+Xn5+uFF17Q7373O5cVBwAAUBGcul0zZ84cPfjgg2rUqJHatWsnSdqxY4cCAwP11ltvubRAoCrKfrG1u0vAb9w5+Qd3lwCgmnEqAIWGhur777/X22+/rZ07d6pWrVpKTEzU4MGDVbNmTVfXCAAA4FJOL9ipU6eOOnXqpDvvvFMlJSWSpE8//VSS9Pvf/9411QEAAFQApwLQwYMH9Yc//EE//PCDbDabLMuSzWazHy8tLXVZgQAAAK7m1CLosWPHqnHjxjpx4oRq166tXbt2acOGDerQoYPS09NdXCIAAIBrOXUHKCMjQ+vXr1dAQIA8PDzk6empTp06KSUlRWPGjNH27dtdXScAAIDLOHUHqLS0VPXq1ZMkBQQE6NixY5KkRo0aad++fa6rDgAAoAI4dQeoVatW2rlzpxo3bqzo6GjNmjVLXl5eeuONN9SkSRNX1wgAAOBSTgWgiRMnqri4WJL04osvqnfv3urcubP8/f21evVqlxYIAADgak4FoPj4ePvPTZs21d69e3XmzBn5+fk5vBsMAACgKnLZF3c1bNjQVUMBAABUKKcWQbvSwoULFR4eLh8fH0VHR2vz5s1X7Lt792498sgjCg8Pl81m0/z58296TAAAYB63BqDVq1crKSlJU6ZM0bZt29SmTRvFx8frxIkT5fY/f/68mjRpohkzZigoKMglYwIAAPO4NQDNmzdPI0aMUGJiolq2bKlFixapdu3aWrJkSbn9O3bsqNmzZ2vQoEHy9vZ2yZgAAMA8bgtAJSUl2rp1q+Li4v5TjIeH4uLilJGRUaljXrhwQYWFhQ4bAAC4dblsEfSNOnXqlEpLSxUYGOjQHhgYqL1791bqmCkpKfrrX//q1GteEjl+xU2dD9faOjvB3SUAAKowty+CrgqSk5NVUFBg33JyctxdEgAAqEBuuwMUEBAgT09P5eXlObTn5eVdcYFzRY3p7e19xTVFAADg1uO2O0BeXl6KjIxUWlqava2srExpaWmKiYmpMmMCAIBbj9vuAElSUlKShg4dqg4dOigqKkrz589XcXGxEhMTJUkJCQkKDQ1VSkqKpF8XOe/Zs8f+89GjR7Vjxw7VrVtXTZs2va4xAQAA3BqABg4cqJMnT2ry5MnKzc1V27ZtlZqaal/EnJ2dLQ+P/9ykOnbsmNq1a2ffnzNnjubMmaPY2Filp6df15gAAABuDUCSNGrUKI0aNarcY5dCzSXh4eGyLOumxgQAAOBdYAAAwDgEIAAAYBwCEAAAMA4BCAAAGIcABAAAjEMAAgAAxiEAAQAA4xCAAACAcdz+QYgAUNU98NoD7i4Bv7Fx9EZ3l4BbAHeAAACAcQhAAADAOAQgAABgHAIQAAAwDgEIAAAYhwAEAACMQwACAADGIQABAADjEIAAAIBxCEAAAMA4BCAAAGAcAhAAADAOAQgAABiHAAQAAIxDAAIAAMYhAAEAAOMQgAAAgHEIQAAAwDgEIAAAYBwCEAAAMA4BCAAAGIcABAAAjEMAAgAAxiEAAQAA4xCAAACAcQhAAADAOAQgAABgHAIQAAAwDgEIAAAYhwAEAACMQwACAADGIQABAADjEIAAAIBxCEAAAMA4BCAAAGAcAhAAADAOAQgAABiHAAQAAIxDAAIAAMYhAAEAAOMQgAAAgHEIQAAAwDgEIAAAYBwCEAAAMA4BCAAAGIcABAAAjEMAAgAAxiEAAQAA4xCAAACAcQhAAADAOAQgAABgHAIQAAAwDgEIAAAYp0oEoIULFyo8PFw+Pj6Kjo7W5s2br9r/vffe0z333CMfHx+1bt1aa9eudTg+bNgw2Ww2h61Hjx4VOQUAAFCNuD0ArV69WklJSZoyZYq2bdumNm3aKD4+XidOnCi3/7fffqvBgwdr+PDh2r59u/r166d+/fpp165dDv169Oih48eP27d33nmnMqYDAACqAbcHoHnz5mnEiBFKTExUy5YttWjRItWuXVtLliwpt/8rr7yiHj16aPz48WrRooWmTZum9u3ba8GCBQ79vL29FRQUZN/8/PwqYzoAAKAacGsAKikp0datWxUXF2dv8/DwUFxcnDIyMso9JyMjw6G/JMXHx1/WPz09XbfffrvuvvtuPfnkkzp9+vQV67hw4YIKCwsdNgAAcOtyawA6deqUSktLFRgY6NAeGBio3Nzccs/Jzc29Zv8ePXpoxYoVSktL08yZM7Vhwwb17NlTpaWl5Y6ZkpIiX19f+xYWFnaTMwMAAFVZDXcXUBEGDRpk/7l169aKiIjQXXfdpfT0dHXr1u2y/snJyUpKSrLvFxYWEoIAALiFufUOUEBAgDw9PZWXl+fQnpeXp6CgoHLPCQoKuqH+ktSkSRMFBATowIED5R739vZW/fr1HTYAAHDrcmsA8vLyUmRkpNLS0uxtZWVlSktLU0xMTLnnxMTEOPSXpHXr1l2xvyQdOXJEp0+fVnBwsGsKBwAA1Zrb3wWWlJSkxYsXa/ny5crKytKTTz6p4uJiJSYmSpISEhKUnJxs7z927FilpqZq7ty52rt3r6ZOnaotW7Zo1KhRkqSioiKNHz9emzZt0uHDh5WWlqa+ffuqadOmio+Pd8scAQBA1eL2NUADBw7UyZMnNXnyZOXm5qpt27ZKTU21L3TOzs6Wh8d/ctr999+vlStXauLEiXrhhRfUrFkzrVmzRq1atZIkeXp66vvvv9fy5cuVn5+vkJAQde/eXdOmTZO3t7db5ggAAKoWtwcgSRo1apT9Ds5/S09Pv6xtwIABGjBgQLn9a9Wqpc8++8yV5QEAgFuM2x+BAQAAVDYCEAAAMA4BCAAAGIcABAAAjEMAAgAAxiEAAQAA4xCAAACAcQhAAADAOAQgAABgHAIQAAAwDgEIAAAYhwAEAACMQwACAADGIQABAADjEIAAAIBxCEAAAMA4BCAAAGAcAhAAADAOAQgAABiHAAQAAIxDAAIAAMYhAAEAAOMQgAAAgHEIQAAAwDgEIAAAYBwCEAAAMA4BCAAAGIcABAAAjEMAAgAAxiEAAQAA4xCAAACAcQhAAADAOAQgAABgHAIQAAAwDgEIAAAYhwAEAACMQwACAADGIQABAADjEIAAAIBxCEAAAMA4BCAAAGAcAhAAADAOAQgAABiHAAQAAIxDAAIAAMYhAAEAAOMQgAAAgHEIQAAAwDgEIAAAYBwCEAAAMA4BCAAAGIcABAAAjEMAAgAAxiEAAQAA4xCAAACAcQhAAADAOAQgAABgHAIQAAAwDgEIAAAYhwAEAACMQwACAADGIQABAADjEIAAAIBxqkQAWrhwocLDw+Xj46Po6Ght3rz5qv3fe+893XPPPfLx8VHr1q21du1ah+OWZWny5MkKDg5WrVq1FBcXp/3791fkFAAAQDXi9gC0evVqJSUlacqUKdq2bZvatGmj+Ph4nThxotz+3377rQYPHqzhw4dr+/bt6tevn/r166ddu3bZ+8yaNUuvvvqqFi1apMzMTNWpU0fx8fH6+eefK2taAACgCnN7AJo3b55GjBihxMREtWzZUosWLVLt2rW1ZMmScvu/8sor6tGjh8aPH68WLVpo2rRpat++vRYsWCDp17s/8+fP18SJE9W3b19FRERoxYoVOnbsmNasWVOJMwMAAFVVDXe+eElJibZu3ark5GR7m4eHh+Li4pSRkVHuORkZGUpKSnJoi4+Pt4ebQ4cOKTc3V3Fxcfbjvr6+io6OVkZGhgYNGnTZmBcuXNCFCxfs+wUFBZKkwsLC655L6YV/X3dfVLwbuXbOOPdzaYWOjxtT0df7l3//UqHj48ZU9PUu/oXrXZXcyPW+1NeyrGv2dWsAOnXqlEpLSxUYGOjQHhgYqL1795Z7Tm5ubrn9c3Nz7ccvtV2pz39LSUnRX//618vaw8LCrm8iqHJ8X/uLu0tAZUrxdXcFqES+E7jeRvG98et97tw5+V7jPLcGoKoiOTnZ4a5SWVmZzpw5I39/f9lsNjdWVrkKCwsVFhamnJwc1a9f393loIJxvc3C9TaLqdfbsiydO3dOISEh1+zr1gAUEBAgT09P5eXlObTn5eUpKCio3HOCgoKu2v/Sf+bl5Sk4ONihT9u2bcsd09vbW97e3g5tDRo0uJGp3FLq169v1C+M6bjeZuF6m8XE632tOz+XuHURtJeXlyIjI5WWlmZvKysrU1pammJiYso9JyYmxqG/JK1bt87ev3HjxgoKCnLoU1hYqMzMzCuOCQAAzOL2R2BJSUkaOnSoOnTooKioKM2fP1/FxcVKTEyUJCUkJCg0NFQpKSmSpLFjxyo2NlZz587Vww8/rFWrVmnLli164403JEk2m03jxo3T9OnT1axZMzVu3FiTJk1SSEiI+vXr565pAgCAKsTtAWjgwIE6efKkJk+erNzcXLVt21apqan2RczZ2dny8PjPjar7779fK1eu1MSJE/XCCy+oWbNmWrNmjVq1amXv89xzz6m4uFhPPPGE8vPz1alTJ6WmpsrHx6fS51edeHt7a8qUKZc9DsStiettFq63Wbje12azrue9YgAAALcQt38QIgAAQGUjAAEAAOMQgAAAgHEIQLe48PBwzZ8//7r7T5069Yqfl3QjbDYb373mYl26dNG4ceMq/fzDhw/LZrNpx44dV+yTnp4um82m/Px8p+vD9bnZ/x3ciOu59qh6li1bZvRn2V0vAhCAqwoLC9Px48cd3mkJoOoaOHCgfvzxR3eXUeW5/W3wAKqukpISeXl5XfGT2QFUPbVq1VKtWrXcXUaVxx2gau7cuXMaMmSI6tSpo+DgYL388stXvUWenZ2tvn37qm7duqpfv74effTRy75aRJL+/ve/KywsTLVr19ajjz6qgoIC+7HvvvtOv/vd7xQQECBfX1/FxsZq27ZtFTVF/EZZWZmee+45NWzYUEFBQZo6daok6c9//rN69+7t0PfixYu6/fbb9eabb9rbfvnlF40aNUq+vr4KCAjQpEmTHL41OTw8XNOmTVNCQoLq16+vJ554otzHIGvXrlXz5s1Vq1YtPfTQQzp8+HBFThtXcPbsWSUkJMjPz0+1a9dWz549tX//foc+GzduVJcuXVS7dm35+fkpPj5eZ8+elSSlpqaqU6dOatCggfz9/dW7d2/99NNP7pgKfqNLly4aM2ZMub/rkjRv3jy1bt1aderUUVhYmEaOHKmioiL78d8+Avvxxx9ls9ku+4Lxl19+WXfddZd9f9euXerZs6fq1q2rwMBAPfbYYzp16lSFztPdCEDVXFJSkjZu3KiPP/5Y69at09dff33FMFJWVqa+ffvqzJkz2rBhg9atW6eDBw9q4MCBDv0OHDigd999V5988olSU1O1fft2jRw50n783LlzGjp0qL755htt2rRJzZo1U69evXTu3LkKnSuk5cuXq06dOsrMzNSsWbP04osvat26dXr88ceVmpqq48eP2/v+61//0vnz5x2u7/Lly1WjRg1t3rxZr7zyiubNm6f//d//dXiNOXPmqE2bNtq+fbsmTZp0WQ05OTnq37+/+vTpox07dujxxx/X888/X3GTxhUNGzZMW7Zs0ccff6yMjAxZlqVevXrp4sWLkqQdO3aoW7duatmypTIyMvTNN9+oT58+Ki0tlSQVFxcrKSlJW7ZsUVpamjw8PPSHP/xBZWVl7pwWdOXfdUny8PDQq6++qt27d2v58uVav369nnvuuXLHad68uTp06KC3337bof3tt9/Wn/70J0lSfn6+unbtqnbt2mnLli1KTU1VXl6eHn300YqdpLtZqLYKCwutmjVrWu+99569LT8/36pdu7Y1duxYy7Isq1GjRtbLL79sWZZlff7555anp6eVnZ1t7797925LkrV582bLsixrypQplqenp3XkyBF7n08//dTy8PCwjh8/Xm4dpaWlVr169axPPvnE3ibJ+vDDD100U1iWZcXGxlqdOnVyaOvYsaM1YcIEy7Isq2XLltbMmTPtx/r06WMNGzbM4fwWLVpYZWVl9rYJEyZYLVq0sO83atTI6tevn8NrHDp0yJJkbd++3bIsy0pOTrZatmzp0GfChAmWJOvs2bM3NUdcW2xsrDV27Fjrxx9/tCRZGzdutB87deqUVatWLevdd9+1LMuyBg8ebD3wwAPXPfbJkyctSdYPP/xgWdbl1x6V41q/6//tvffes/z9/e37S5cutXx9fe37L7/8snXXXXfZ9/ft22dJsrKysizLsqxp06ZZ3bt3dxgzJyfHkmTt27fvZqdTZXEHqBo7ePCgLl68qKioKHubr6+v7r777nL7Z2VlKSwsTGFhYfa2li1bqkGDBsrKyrK33XnnnQoNDbXvx8TEqKysTPv27ZMk5eXlacSIEWrWrJl8fX1Vv359FRUVKTs729VTxH+JiIhw2A8ODtaJEyckSY8//riWLl0q6ddr9Omnn+rPf/6zQ//77rtPNpvNvh8TE6P9+/fb7whIUocOHa5aQ1ZWlqKjox3a+KLhypeVlaUaNWo4XAt/f3/dfffd9t/nS3eArmT//v0aPHiwmjRpovr16ys8PFyS+F2uAq72u/7FF1+oW7duCg0NVb169fTYY4/p9OnTOn/+fLljDRo0SIcPH9amTZsk/Xr3p3379rrnnnskSTt37tSXX36punXr2rdLx27lR6IEINywoUOHaseOHXrllVf07bffaseOHfL391dJSYm7S7vl1axZ02HfZrPZH1ckJCTo4MGDysjI0D/+8Q81btxYnTt3vuHXqFOnjktqhftdayFsnz59dObMGS1evFiZmZnKzMyUJH6Xq4Ar/a4fPnxYvXv3VkREhD744ANt3bpVCxculHTl6xYUFKSuXbtq5cqVkqSVK1dqyJAh9uNFRUX2R9q/3fbv368HH3ywgmbofgSgaqxJkyaqWbOmvvvuO3tbQUHBFd/+2KJFC+Xk5CgnJ8fetmfPHuXn56tly5b2tuzsbB07dsy+v2nTJnl4eNjvLG3cuFFjxoxRr169dO+998rb2/uWXyxXHfj7+6tfv35aunSpli1bpsTExMv6XPoDd8mlNVyenp7X/TotWrTQ5s2bLxsHlatFixb65ZdfHK7p6dOntW/fPvvvc0REhNLS0so9/1LfiRMnqlu3bmrRooV9cTSqrq1bt6qsrExz587Vfffdp+bNmzv8e30lQ4YM0erVq5WRkaGDBw9q0KBB9mPt27fX7t27FR4erqZNmzpst/L/ISIAVWP16tXT0KFDNX78eH355ZfavXu3hg8fLg8PD4fHHJfExcWpdevWGjJkiLZt26bNmzcrISFBsbGxDo89fHx8NHToUO3cuVNff/21xowZo0cffdT+VuhmzZrprbfeUlZWljIzMzVkyBDecllFPP7441q+fLmysrI0dOjQy45nZ2crKSlJ+/bt0zvvvKPXXntNY8eOvaHX+Mtf/qL9+/dr/Pjx2rdvn1auXKlly5a5aAa4Xs2aNVPfvn01YsQIffPNN9q5c6f+53/+R6Ghoerbt68kKTk5Wd99951Gjhyp77//Xnv37tXrr7+uU6dOyc/PT/7+/nrjjTd04MABrV+/XklJSW6eFa6ladOmunjxol577TUdPHhQb731lhYtWnTN8/r3769z587pySef1EMPPaSQkBD7saeeekpnzpzR4MGD9d133+mnn37SZ599psTERIfH47caAlA1N2/ePMXExKh3796Ki4vTAw88oBYtWsjHx+eyvjabTR999JH8/Pz04IMPKi4uTk2aNNHq1asd+jVt2lT9+/dXr1691L17d0VEROhvf/ub/fibb76ps2fPqn379nrsscc0ZswY3X777RU+V1xbXFycgoODFR8f7/AP3CUJCQn697//raioKD311FMaO3asnnjiiRt6jTvvvFMffPCB1qxZozZt2mjRokV66aWXXDUF3IClS5cqMjJSvXv3VkxMjCzL0tq1a+2PT5o3b67PP/9cO3fuVFRUlGJiYvTRRx+pRo0a8vDw0KpVq7R161a1atVKTz/9tGbPnu3mGeFa2rRpo3nz5mnmzJlq1aqV3n77baWkpFzzvHr16qlPnz7auXOnw+MvSQoJCdHGjRtVWlqq7t27q3Xr1ho3bpwaNGggD49bNybYLOs3HwKCaq+4uFihoaGaO3euhg8f7u5yUMmKiooUGhqqpUuXqn///u4uBwCqLD4Juprbvn279u7dq6ioKBUUFOjFF1+UJPstcJihrKxMp06d0ty5c9WgQQP9/ve/d3dJAFClEYBuAXPmzNG+ffvk5eWlyMhIff311woICHB3WahE2dnZaty4se644w4tW7ZMNWrwqw0AV8MjMAAAYJxbd3UTAADAFRCAAACAcQhAAADAOAQgAABgHAIQAPyXLl26aNy4ce4uA0AFIgABAADjEIAAAIBxCEAAqo0uXbpo9OjRGjdunPz8/BQYGKjFixeruLhYiYmJqlevnpo2bapPP/3Ufs6GDRsUFRUlb29vBQcH6/nnn9cvv/xiP15cXKyEhATVrVtXwcHBmjt37mWve+HCBT377LMKDQ1VnTp1FB0drfT09MqYMoAKQgACUK0sX75cAQEB2rx5s0aPHq0nn3xSAwYM0P33369t27ape/fueuyxx3T+/HkdPXpUvXr1UseOHbVz5069/vrrevPNNzV9+nT7eOPHj9eGDRv00Ucf6fPPP1d6erq2bdvm8JqjRo1SRkaGVq1ape+//14DBgxQjx49tH///sqePgAX4ZOgAVQbXbp0UWlpqb7++mtJUmlpqXx9fdW/f3+tWLFCkpSbm6vg4GBlZGTok08+0QcffKCsrCzZbDZJ0t/+9jdNmDBBBQUFOn/+vPz9/fWPf/xDAwYMkCSdOXNGd9xxh5544gnNnz9f2dnZatKkibKzsxUSEmKvJS4uTlFRUXrppZcq+b8FAK7AFwYBqFYiIiLsP3t6esrf31+tW7e2twUGBkqSTpw4oaysLMXExNjDjyQ98MADKioq0pEjR3T27FmVlJQoOjrafrxhw4a6++677fs//PCDSktL1bx5c4c6Lly4IH9/f5fPD0DlIAABqFZq1qzpsG+z2RzaLoWdsrIyl7xeUVGRPD09tXXrVnl6ejocq1u3rkteA0DlIwABuGW1aNFCH3zwgSzLsgejjRs3ql69errjjjvUsGFD1axZU5mZmbrzzjslSWfPntWPP/6o2NhYSVK7du1UWlqqEydOqHPnzm6bCwDXYhE0gFvWyJEjlZOTo9GjR2vv3r366KOPNGXKFCUlJcnDw0N169bV8OHDNX78eK1fv167du3SsGHD5OHxn38amzdvriFDhighIUH//Oc/dejQIW3evFkpKSn6v//7PzfODsDN4A4QgFtWaGio1q5dq/Hjx6tNmzZq2LChhg8frokTJ9r7zJ49W0VFRerTp4/q1aunZ555RgUFBQ7jLF26VNOnT9czzzyjo0ePKiAgQPfdd5969+5d2VMC4CK8CwwAABiHR2AAAMA4BCAAAGAcAhAAADAOAQgAABiHAAQAAIxDAAIAAMYhAAEAAOMQgAAAgHEIQAAAwDgEIAAAYBwCEAAAMA4BCAAAGOf/A7S2cTMHk8BIAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "\n",
    "sns.barplot(x='mode', y='accuracy', data=metrics_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df3c542c-60e0-4247-9524-fc7b9026235c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
